package net.sangpil.classes.media.video
{
	import flash.events.NetStatusEvent;
	import flash.events.SecurityErrorEvent;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	
	import net.sangpil.classes.events.VideoWithUrlEvent;

	[Event(name = "video_loaded", type = "net.sangpil.classes.events.VideoWithUrlEvent")]
	[Event(name = "video_replay", type = "net.sangpil.classes.events.VideoWithUrlEvent")]
	public class VideoWithUrl extends Video
	{
		private var ns:NetStream;
		private var nc:NetConnection;
		private var client:Object;
		private var url:String;
		private var savedUrl:String;
		private var metaData:Object;
		private var loopTf:Boolean;
		
		public function VideoWithUrl(width:int=320, height:int=240, loop:Boolean = true)
		{
			super(width, height);
			this.loopTf = loop;
		}
		
		/* public function*/
		
		/**
		 * NetConnection start.
		 * @param url URL string value
		 * 
		 */		
		public function movieLoad(url:String):void
		{
			//this.savedUrl = null;
			this.reset();
			this.url = url;
			this.nc = new NetConnection();
			this.nc.addEventListener(NetStatusEvent.NET_STATUS, this.netStatusHandler);
			this.nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorHandler);
			this.nc.connect(null);
		}
		
		public function resume():void
		{
			if(this.ns){this.ns.resume();}
		}
		
		public function seek(num:Number):void
		{
			if(this.ns){this.ns.seek(num);}
		}
		
		public function stop():void
		{
			if(this.ns){this.ns.seek(1); this.ns.pause();}
		}
		
		public function pause():void
		{
			if(this.ns){this.ns.pause();}
		}
		
		public function get currentFrame():Number
		{
			if(this.ns){return this.ns.time;}else{return 0;}
		}
		
		public function get duration():Number
		{
			if(this.ns && this.metaData){
				return this.metaData.duration;
			}else{
				return 0; 
			}
		}
		
		/* private function  */
		
		/**
		 * when NetConnection info is "NetConnection.Connect.Success"
		 * this method start NetStream.
		 */		
		private function connectStream():void
		{
			this.client = new Object();
			this.client.onMetaData = onMetaDataCallBack;
			
			this.ns = new NetStream(this.nc);
			this.ns.client = this.client;
			this.ns.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
			
			this.attachNetStream(this.ns);			
			this.ns.play(url);
		}
		
		/* event handler */		
		
		/**
		 * NetStatusEvent Handler 
		 * @param e
		 * 
		 */		
		private function netStatusHandler(e:NetStatusEvent):void
		{
			//trace(e.info.code);	
			switch(e.info.code)
			{
				case "NetConnection.Connect.Success":
					trace("video connect start");
                    this.connectStream();
                    break;
                case "NetStream.Play.StreamNotFound":
                    trace("Unable to locate video: " + this.url);
                    break;    
                case "NetStream.Play.Stop":
                	trace("stop");
                	this.ns.seek(0);
                	if(!this.loopTf)
                	{
                		this.ns.pause();
                	}
                	break;
                case "NetStream.Play.Start":
                	break;
			}
		}
		
		/**
		 * security error event handler 
		 * @param e
		 * 
		 */		
		private function securityErrorHandler(e:SecurityErrorEvent):void
		{
			trace("error : " + e);
		}
		
		private function onMetaDataCallBack(meta:Object):void
		{
			this.metaData = meta;
			this.width = meta.width;
			this.height = meta.height;
			
			var vidInfo:VideoInfo = new VideoInfo();
        	vidInfo.duration = this.metaData.duration;
        	vidInfo.width = this.metaData.width;
        	vidInfo.height = this.metaData.height;
        	vidInfo.url = this.url;
        	/* when metatdata maked */
        	
        	if(!this.savedUrl)
        	{
        		this.dispatchEvent(new VideoWithUrlEvent(vidInfo, VideoWithUrlEvent.VIDEO_LOADED));
        	}else{
        		this.dispatchEvent(new VideoWithUrlEvent(vidInfo, VideoWithUrlEvent.VIDEO_REPLAY));
        	}
			
			/* for(var i:String in meta)
			{
				trace(i + " : " + meta[i]);
			} */
			
			this.savedUrl = this.url;
		}
		
		/* reset */
		
		/**
		 * reset netconnection, netstream. 
		 * 
		 */		
		private function reset():void
		{
			if(this.nc){
				this.nc.removeEventListener(NetStatusEvent.NET_STATUS, this.netStatusHandler);
				this.nc.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityErrorHandler);
				nc.close(); 
				this.nc = null; 
			}
			if(this.ns){ 
				this.ns.removeEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
				ns.close(); 
				this.ns = null; 
			}
			if(this.client)
			{
				this.client = null;
			}
		}
	}
}